﻿/**	archive_supported_UDT.hpp
 *	----	Create Time Stamp	--2009-01-25 14:04:49--
 *------------------------------------------------------------------------------
 *	Mean	:
 *	Author	:Nick Shallery	(nicknide@gmail.com)
 *	Version	:1.0.7.12	(2009-08-30 00:50:11)
 *------------------------------------------------------------------------------
**/	/*YOU HAVE ALL LEFT WITH THIS CODE WHILE YOU KEEP COMMENT IN EVERY COPY.*/

#if			!defined(__LOLIX_TOY__ARCHIVE__SUPPORTED_UDT__NICK__K_IN_G__)
#define		__LOLIX_TOY__ARCHIVE__SUPPORTED_UDT__NICK__K_IN_G__
//==============================================================================
//--------------------------------------------------------------------------

#if			!defined(__LOLIX_TOY__ARCHIVE__SUPPORTED_UDT__NICK__K_IN_G__)
	#include	"./archive.hpp"
#endif	//	!defined(__LOLIX_TOY__ARCHIVE__SUPPORTED_UDT__NICK__K_IN_G__)

#if			defined(LOLIX_DEF__ARC_SUPPORT_ALL)
	#define	LOLIX_DEF__ARC_SUPPORT_KEY_BIND
	#define	LOLIX_DEF__ARC_SUPPORT_LIST
	#define	LOLIX_DEF__ARC_SUPPORT_STRING
	#define	LOLIX_DEF__ARC_SUPPORT_VECTOR
	#define	LOLIX_DEF__ARC_SUPPORT_VEC_MAP

#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_ALL)


namespace lolix{namespace toy{
	template<typename _Teh, typename _TPmap, typename _TDat>
	LOLIX_INLINE_CALL archive_base<_Teh, _TPmap>& operator << (archive_base<_Teh, _TPmap>& arc, const _TDat& val)
		{
		return _help::__ArcWrite(arc, val, &_TDat::write);
		}
	template<typename _Teh, typename _TPmap, typename _TDat>
	LOLIX_INLINE_CALL archive_base<_Teh, _TPmap>& operator >> (archive_base<_Teh, _TPmap>& arc, _TDat& val)
		{
		return _help::__ArcRead(arc, val, &_TDat::read);
		}
}}


#define		LOLIX_DEFINE__SUPPORT_ARCHIVE_WRITE_TEMPLATE(type)	\
	template<typename _Teh, typename _TPmap>	LOLIX_INLINE_CALL\
	::lolix::toy::archive_base<_Teh, _TPmap>& operator << (::lolix::toy::archive_base<_Teh, _TPmap>& arc, type& val)\
	{\
		return ::lolix::toy::_help::__ArcWrite(arc, val, &type::write<::lolix::toy::archive_base<_Teh, _TPmap> >);\
	}

#define		LOLIX_DEFINE__SUPPORT_ARCHIVE_READ_TEMPLATE(type)	\
	template<typename _Teh, typename _TPmap>	LOLIX_INLINE_CALL\
	::lolix::toy::archive_base<_Teh, _TPmap>& operator >> (::lolix::toy::archive_base<_Teh, _TPmap>& arc, type& val)\
	{\
		return ::lolix::toy::_help::__ArcRead(arc, val, &type::read<::lolix::toy::archive_base<_Teh, _TPmap> >);\
	}

#define		LOLIX_DEFINE__SUPPORT_ARCHIVE_READ_WRITE_TEMPLATE(type)	\
	LOLIX_DEFINE__SUPPORT_ARCHIVE_READ_TEMPLATE(type)\
	LOLIX_DEFINE__SUPPORT_ARCHIVE_WRITE_TEMPLATE(type)

#define		LOLIX_DEFINE__SUPPORT_ARCHIVE_BLOCK(type)	\
	template<typename _Teh, typename _TPmap>	LOLIX_INLINE_CALL\
	::lolix::toy::archive_base<_Teh, _TPmap>& operator >> (::lolix::toy::archive_base<_Teh, _TPmap>& arc, type& val)\
	{\
		return arc.read(&val, sizeof val);\
	}\
	template<typename _Teh, typename _TPmap>	LOLIX_INLINE_CALL\
	::lolix::toy::archive_base<_Teh, _TPmap>& operator << (::lolix::toy::archive_base<_Teh, _TPmap>& arc, const type& val)\
	{\
		return arc.write(&val, sizeof val);\
	}


namespace lolix{namespace toy{
#define	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(type)	\
	template<typename _Teh, typename _TPmap>	LOLIX_INLINE_CALL\
	archive_base<_Teh, _TPmap>& operator << (archive_base<_Teh, _TPmap>& arc, type val){ return arc.write(&val, sizeof val); }\
	template<typename _Teh, typename _TPmap>	LOLIX_INLINE_CALL\
	archive_base<_Teh, _TPmap>& operator >> (archive_base<_Teh, _TPmap>& arc, type& val){ return arc.read(&val, sizeof val); }

	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_u8);
	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_u16);

	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_i8);
	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_i16);

	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_f32);
	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_f64);

	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(char);
	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(__wchar_t);

	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(LOLIX_ITF_ID);

#undef	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE

	class	size_value
	{
		lx_u64	_val;

		union _T_sv_dat
		{
			struct
			{
				lx_u32	dat_l;
				lx_u32	dat_h;
			};
			lx_u64	dat;

			LOLIX_INLINE_CALL void operator >>= (lx_u32 i)
			{
				//	i during [0, 32)
#if			LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
				dat_l >>= i;
				dat_l |= (dat_h<<(32-i));
				dat_h >>= i;
#else	//	LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
				dat >>= i;
#endif	//	LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
			}

			LOLIX_INLINE_CALL void operator <<= (lx_u32 i)
			{
				//	i during [0, 32)
#if			LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
				if ( i <= 31 )
				{
					dat_h <<= i;
					dat_h |= (dat_l >> (32-i));
					dat_l <<= i;
				}
				else
				{
					dat_h = (dat_l<<(i-32));
					dat_l = 0;
				}

#else	//	LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
				dat <<= i;

#endif	//	LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
			}

			LOLIX_INLINE_CALL lx_u8 get_bits(void)const
			{
				lx_u8 len_size = 0;
#if			LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
				lx_u32 tmp = 0xffffffff;
				for ( lx_u8 i = 0; i != 32 && (dat_l & tmp); ++i, (tmp <<= 1) )
					if ( dat_l | (1<<i) )
						len_size = i;

				tmp = 0xffffffff;
				for ( lx_u8 i = 0; i != 32 && (dat_h & tmp); ++i, (tmp<<=1) )
					if ( dat_h | (1<<i) )
						len_size = 32 + i;

#else	//	LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
				lx_u64 tmp = ~0ull;
				for ( lx_u8 i = 0; i != 64 && (dat & tmp); ++i, (tmp <<= 1) )
					if ( dat | (1ull<<i) )
						len_size = i;

#endif	//	LOLIX_CFG__SIZE_TYPE_BITS_SIZE <= 32
				return len_size + 1;
			}
		};
	public:
		LOLIX_INLINE_CALL	size_value(void){}
		template<typename _Ty>
		LOLIX_INLINE_CALL	explicit size_value(_Ty val):_val(val){}
		template<typename _Ty>
		LOLIX_INLINE_CALL	operator _Ty(void)const
		{
			return (_Ty)(lolix::type::type_value<_Ty>::max_val & _val);
		}

		template<typename _Tarc>
		LOLIX_INLINE_CALL void read(_Tarc& arc)
		{
			lx_u8 opval;
			arc >> opval;
			const lx_u8 len_size = (opval & 0x0f);
			_T_sv_dat dat;
			dat.dat_h = 0;
			dat.dat_l = (opval >>= 4);
			for ( lx_u8 i = 0; i != len_size; ++i )
			{
				arc >> opval;
				_T_sv_dat tmp;
				tmp.dat_h = 0;
				tmp.dat_l = opval;
				tmp <<= (i*8 + 4);
				dat.dat_l |= tmp.dat_l;
				dat.dat_h |= tmp.dat_h;
			}

			_val = dat.dat;
		}
		template<typename _Tarc>
		LOLIX_INLINE_CALL void write(_Tarc& arc)const
		{
			_T_sv_dat sv_dat;
			sv_dat.dat = _val;

			lx_u8 len_size = sv_dat.get_bits();

			len_size += 4;
			len_size /= 8;

			lx_u8 ipval = len_size;
			LOLIX_ASSERT(ipval <= 8, L"len_size over flow");
			ipval |= ((sv_dat.dat_l & 0x0f)<<4);
			arc << ipval;
			sv_dat >>= 4;
			for ( lx_u8 i = 0; i != len_size; ++i )
			{
				ipval = (lx_u8)sv_dat.dat_l&0xff;
				sv_dat >>= 8;
				arc << ipval;
			}
		}
	};
	LOLIX_DEFINE__SUPPORT_ARCHIVE_READ_WRITE_TEMPLATE(size_value);


#define	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(type)	\
	template<typename _Teh, typename _TPmap>	LOLIX_INLINE_CALL\
	archive_base<_Teh, _TPmap>& operator << (archive_base<_Teh, _TPmap>& arc, type val){ size_value sv(val); return arc<<sv; }\
	template<typename _Teh, typename _TPmap>	LOLIX_INLINE_CALL\
	archive_base<_Teh, _TPmap>& operator >> (archive_base<_Teh, _TPmap>& arc, type& val){ size_value sv; arc >> sv; val = (type)sv; return arc; }

	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_u32);
	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_u64);
	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_i32);
	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(lx_i64);

	//__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE(wchar_t);

#undef	__LOLIX_TMP_DEFINE__ARC_STANDE_TYPE

	template<typename _Teh, typename _TPmap, enum _Tenum>	LOLIX_INLINE_CALL
		archive_base<_Teh, _TPmap>& operator << (archive_base<_Teh, _TPmap>& arc, enum _Tenum ve){ lx_u32 val = ve; return arc << val; }
	template<typename _Teh, typename _TPmap, enum _Tenum>	LOLIX_INLINE_CALL
		archive_base<_Teh, _TPmap>& operator >> (archive_base<_Teh, _TPmap>& arc, enum _Tenum& ve){ lx_u32 val; archive_base<_Teh, _TPmap>& rtv = arc >> val; va = (_Tenum)val; return rtv; }

	template<typename _Teh, typename _TPmap, typename _Tv, size_type array_size>	LOLIX_INLINE_CALL
		archive_base<_Teh, _TPmap>& operator << (archive_base<_Teh, _TPmap>& arc, _Tv (&val)[array_size])
		{
		for ( size_type i = 0; i != array_size; ++i )
			arc << val[i];
		return arc;
		}
	template<typename _Teh, typename _TPmap, typename _Tv, size_type array_size>	LOLIX_INLINE_CALL
		archive_base<_Teh, _TPmap>& operator >> (archive_base<_Teh, _TPmap>& arc, _Tv (&val)[array_size])
		{
		for ( size_type i = 0; i != array_size; ++i )
			arc >> val[i];
		return arc;
		}
}}


namespace lolix{namespace toy{namespace _help{

	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	template<typename _Tr>
	struct __ArcReadWrite_S
	{
		template<typename _Tarc, typename _Tval>
		static LOLIX_INLINE_CALL _Tarc& write(_Tarc& arc, _Tval& val)
			{
			val.write(arc);
			return arc;
			}
		template<typename _Tarc, typename _Tval>
		static LOLIX_INLINE_CALL _Tarc& read(_Tarc& arc, _Tval& val)
			{
			val.read(arc);
			return arc;
			}
	};

	template<>
	struct __ArcReadWrite_S<bool>
	{
		template<typename _Tarc, typename _Tval>
		static LOLIX_INLINE_CALL _Tarc& write(_Tarc& arc, _Tval& val)
			{
			if ( val.write(arc) )
				return arc;
			_Tarc::error_handle_type& eh = arc.get_eh();
			eh.handle_write_error(arc.get_fs(), 0, 0, LOLIX_ERROR_INVALID_OPERATOR);
			return arc;
			}
		template<typename _Tarc, typename _Tval>
		static LOLIX_INLINE_CALL _Tarc& read(_Tarc& arc, _Tval& val)
			{
			if ( val.read(arc) )
				return arc;
			_Tarc::error_handle_type& eh = arc.get_eh();
			eh.handle_read_error(arc.get_fs(), 0, 0, LOLIX_ERROR_INVALID_OPERATOR);
			return arc;
			}
	};

	template<>
	struct __ArcReadWrite_S<LOLIX_RETNV>
	{
		template<typename _Tarc, typename _Tval>
		static LOLIX_INLINE_CALL _Tarc& write(_Tarc& arc, _Tval& val)
			{
			LOLIX_RETNV rtv;
			if ( !LOLIX_IS_ERROR(rtv = val.write(arc)) )
				return arc;
			_Tarc::error_handle_type& eh = arc.get_eh();
			eh.handle_write_error(arc.get_fs(), 0, 0, rtv);
			return arc;
			}
		template<typename _Tarc, typename _Tval>
		static LOLIX_INLINE_CALL _Tarc& read(_Tarc& arc, _Tval& val)
			{
			LOLIX_RETNV rtv;
			if ( !LOLIX_IS_ERROR(rtv = val.read(arc)) )
				return arc;
			_Tarc::error_handle_type& eh = arc.get_eh();
			eh.handle_read_error(arc.get_fs(), 0, 0, rtv);
			return arc;
			}
	};

	template<typename _Teh, typename _TPmap>
	struct __ArcReadWrite_S< archive_base<_Teh, _TPmap> >
	{
		template<typename _Tarc, typename _Tval>
		static LOLIX_INLINE_CALL _Tarc& write(_Tarc& arc, _Tval& val)
			{
			return val.write(arc);
			}
		template<typename _Tarc, typename _Tval>
		static LOLIX_INLINE_CALL _Tarc& read(_Tarc& arc, _Tval& val)
			{
			return val.read(arc);
			}
	};

#if			LOLIX_CFG__SIZE_TYPE_BITS_SIZE == 32 && !defined(_M_CEE)
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, _Tv& val, _Tr (__thiscall _Tv::*)(_Tarc&))
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, _Tv& val, _Tr (__thiscall _Tv::*)(_Tarc&)const)
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, const _Tv& val, _Tr (__thiscall _Tv::*)(_Tarc&)const)
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}

	////////////////////////////////////////////////////////////////////////////////////
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, _Tv& val, _Tr (__stdcall _Tv::*)(_Tarc&))
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, _Tv& val, _Tr (__stdcall _Tv::*)(_Tarc&)const)
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, const _Tv& val, _Tr (__stdcall _Tv::*)(_Tarc&)const)
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}

	////////////////////////////////////////////////////////////////////////////////////
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, _Tv& val, _Tr (__fastcall _Tv::*)(_Tarc&))
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, _Tv& val, _Tr (__fastcall _Tv::*)(_Tarc&)const)
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, const _Tv& val, _Tr (__fastcall _Tv::*)(_Tarc&)const)
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}

	////////////////////////////////////////////////////////////////////////////////////
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, _Tv& val, _Tr (__cdecl _Tv::*)(_Tarc&))
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, _Tv& val, _Tr (__cdecl _Tv::*)(_Tarc&)const)
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, const _Tv& val, _Tr (__cdecl _Tv::*)(_Tarc&)const)
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////


	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcRead(_Tarc& arc, _Tv& val, _Tr (__thiscall _Tv::*)(_Tarc&))
		{
		return __ArcReadWrite_S<_Tr>::read(arc, val);
		}

	////////////////////////////////////////////////////////////////////////////////////
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcRead(_Tarc& arc, _Tv& val, _Tr (__stdcall _Tv::*)(_Tarc&))
		{
		return __ArcReadWrite_S<_Tr>::read(arc, val);
		}

	////////////////////////////////////////////////////////////////////////////////////
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcRead(_Tarc& arc, _Tv& val, _Tr (__cdecl _Tv::*)(_Tarc&))
		{
		return __ArcReadWrite_S<_Tr>::read(arc, val);
		}

	////////////////////////////////////////////////////////////////////////////////////
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcRead(_Tarc& arc, _Tv& val, _Tr (__fastcall _Tv::*)(_Tarc&))
		{
		return __ArcReadWrite_S<_Tr>::read(arc, val);
		}
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////}}}
#elif		LOLIX_CFG__SIZE_TYPE_BITS_SIZE == 64
	////////////////////////////////////////////////////////////////////////////////////
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, _Tv& val, _Tr (_Tv::*)(_Tarc&))
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, _Tv& val, _Tr (_Tv::*)(_Tarc&)const)
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcWrite(_Tarc& arc, const _Tv& val, _Tr (_Tv::*)(_Tarc&)const)
		{
		return __ArcReadWrite_S<_Tr>::write(arc, val);
		}
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////


	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
	template<typename _Tarc, typename _Tv, typename _Tr>
	_Tarc& __ArcRead(_Tarc& arc, _Tv& val, _Tr (_Tv::*)(_Tarc&))
		{
		return __ArcReadWrite_S<_Tr>::read(arc, val);
		}
	////////////////////////////////////////////////////////////////////////////////////
	////////////////////////////////////////////////////////////////////////////////////
#endif	//	LOLIX_CFG__SIZE_TYPE_BITS_SIZE == 64
}}}


#if			defined(LOLIX_DEF__ARC_SUPPORT_KEY_BIND)
	#if			!defined(__LOLIX__TOY__KEY_BIND__K_IN_G__)
		#include	"./key_bind.hpp"
	#endif	//	!defined(__LOLIX__TOY__KEY_BIND__K_IN_G__)

namespace lolix{namespace toy{namespace _help{
	class key_bind_archive
	{
	public:
	template <typename _KeyBind, typename _Arc>
	LOLIX_INLINE_CALL static _Arc& write(_Arc& arc, _KeyBind const& dat)
		{
		arc << dat.size();
		for ( _KeyBind::const_iterator iter = dat.begin(), iter_end = dat.end()
			; iter != iter_end
				; ++iter )
			{
			_KeyBind::value_type const& val(*iter);
			arc << val.first
				<< val.second;
			}
		return arc;
		}

	template <typename _KeyBind, typename _Arc>
	LOLIX_INLINE_CALL static _Arc& read(_Arc& arc, _KeyBind& dat)
		{
		_KeyBind::size_type dat_size;
		arc >> dat_size;
		_KeyBind new_dat(dat._bind_mode, dat._key_buf.get_allocator());
		for ( size_type i = 0; i != dat_size; ++i )
			{
			typename _KeyBind::key_type key;
			typename _KeyBind::mapped_type val;
			arc >> key >> val;
			typedef key_bind_random<typename _KeyBind::mapped_type, _KeyBind::max_capacity, _KeyBind::row_size, typename _KeyBind::allocator_type>	_Key_random;
			reinterpret_cast<_Key_random&>(new_dat).set_value_by_key((_Key_random::key_type&)(key), val);
			}
		dat.swap(new_dat);
		return arc;
		}
	template <typename _Arc, typename _KeyType>
	LOLIX_INLINE_CALL static _Arc& write_key(_Arc& arc, _KeyType k)
		{
		return arc << k._key;
		}
	template <typename _Arc, typename _KeyType>
	LOLIX_INLINE_CALL static _Arc& read_key(_Arc& arc, _KeyType& k)
		{
		return arc >> k._key;
		}
	};
}}}

namespace lolix{namespace toy{
	template<typename _Teh, typename _TPmap
		, typename _Tbind_type, size_type max_element_size, size_type row_size_input, typename _TAlc, typename need_adjust_free_prev_pointer> LOLIX_INLINE_CALL
		archive_base<_Teh, _TPmap>& operator << (archive_base<_Teh, _TPmap>& arc, key_bind<_Tbind_type, max_element_size, row_size_input, _TAlc, need_adjust_free_prev_pointer> const& dat)
		{
		return _help::key_bind_archive::write(arc, dat);
		}

	template<typename _Teh, typename _TPmap
		, typename _Tbind_type, size_type max_element_size, size_type row_size_input, typename _TAlc, typename need_adjust_free_prev_pointer> LOLIX_INLINE_CALL
		archive_base<_Teh, _TPmap>& operator >> (archive_base<_Teh, _TPmap>& arc, key_bind<_Tbind_type, max_element_size, row_size_input, _TAlc, need_adjust_free_prev_pointer>& dat)
		{
		return _help::key_bind_archive::read(arc, dat);
		}

	template<typename _Teh, typename _TPmap
		, typename _Tbind_type, size_type max_element_size, size_type row_size_input, typename _TAlc> LOLIX_INLINE_CALL
		archive_base<_Teh, _TPmap>& operator << (archive_base<_Teh, _TPmap>& arc, key_bind_random<_Tbind_type, max_element_size, row_size_input, _TAlc> const& dat)
		{
		return _help::key_bind_archive::write(arc, reinterpret_cast<const key_bind<_Tbind_type, max_element_size, row_size_input, _TAlc, type_true>&>(dat));
		}

	template<typename _Teh, typename _TPmap
		, typename _Tbind_type, size_type max_element_size, size_type row_size_input, typename _TAlc> LOLIX_INLINE_CALL
		archive_base<_Teh, _TPmap>& operator >> (archive_base<_Teh, _TPmap>& arc, key_bind_random<_Tbind_type, max_element_size, row_size_input, _TAlc>& dat)
		{
		return _help::key_bind_archive::read(arc, reinterpret_cast<key_bind<_Tbind_type, max_element_size, row_size_input, _TAlc, type_true>&>(dat));
		}


	template<typename _Teh, typename _TPmap, size_type _Max_size, typename _TBind>
	LOLIX_INLINE_CALL archive_base<_Teh, _TPmap>& operator << (archive_base<_Teh, _TPmap>& arc, key_type<_Max_size, _TBind> dat)
		{
		return _help::key_bind_archive::write_key(arc, dat);
		}
	template<typename _Teh, typename _TPmap, size_type _Max_size, typename _TBind>
	LOLIX_INLINE_CALL archive_base<_Teh, _TPmap>& operator >> (archive_base<_Teh, _TPmap>& arc, key_type<_Max_size, _TBind>& dat)
		{
		return _help::key_bind_archive::read_key(arc, dat);
		}

}}
#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_KEY_BIND)


#if			defined(LOLIX_DEF__ARC_SUPPORT_LIST)
	#if			!defined(__LOLIX__TOY__STD_LIST__NICK__K_IN_G__)
		#include	"./std_list.hpp"
	#endif	//	!defined(__LOLIX__TOY__STD_LIST__NICK__K_IN_G__)
namespace lolix{namespace toy{
	template<typename _Teh, typename _TPmap, typename _Ty, typename _Talc> LOLIX_INLINE_CALL
	archive_base<_Teh, _TPmap>&	operator << (archive_base<_Teh, _TPmap>& arc, list<_Ty, _Talc> const& vec)
		{
		size_value sv(vec.size());
		arc << sv;
		for ( list<_Ty, _Talc>::const_iterator iter = vec.begin(), iter_end = vec.end()
			; iter != iter_end
				; ++iter )
			arc << *iter;
		return arc;
		}

	template<typename _Teh, typename _TPmap, typename _Ty, typename _Talc> LOLIX_INLINE_CALL
	archive_base<_Teh, _TPmap>&	operator >> (archive_base<_Teh, _TPmap>& arc, list<_Ty, _Talc>& vec)
		{
		size_value sv;
		arc >> sv;
		vec.clear();
		for ( size_type i = 0; i != (size_type)sv; ++i )
			{
			_Ty tmp;
			arc >> tmp;
			vec.push_back(tmp);
			}
		return arc;
		}
}}
#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_LIST)

#if			defined(LOLIX_DEF__ARC_SUPPORT_STRING)
	#if			!defined(__LOLIX__TOY__STD_STRING__NICK__K_IN_G__)
		#include	"./std_string.hpp"
	#endif	//	!defined(__LOLIX__TOY__STD_STRING__NICK__K_IN_G__)
namespace lolix{namespace toy{
	template<typename _Teh, typename _TPmap, typename _Ty, typename _CT, typename _Talc> LOLIX_INLINE_CALL
	archive_base<_Teh, _TPmap>&	operator << (archive_base<_Teh, _TPmap>& arc, basic_string<_Ty, _CT, _Talc> const& vec)
		{
		lx_u64 sv(vec.size());
		arc << sv;
		for ( size_type i = 0; i != vec.size(); ++i )
			arc << vec[i];
		return arc;
		}

	template<typename _Teh, typename _TPmap, typename _Ty, typename _CT, typename _Talc> LOLIX_INLINE_CALL
	archive_base<_Teh, _TPmap>&	operator >> (archive_base<_Teh, _TPmap>& arc, basic_string<_Ty, _CT, _Talc>& vec)
		{
		lx_u64 sv;
		arc >> sv;
		vec.resize((size_type)sv);
		for ( size_type i = 0; i != vec.size(); ++i )
			arc >> vec[i];
		return arc;
		}
}}
#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_STRING)


#if			defined(LOLIX_DEF__ARC_SUPPORT_VECTOR)
	#if			!defined(__LOLIX__TOY__STD_VECTOR__NICK__K_IN_G__)
		#include	"./std_vector.hpp"
	#endif	//	!defined(__LOLIX__TOY__STD_VECTOR__NICK__K_IN_G__)
namespace lolix{namespace toy{
	template<typename _Teh, typename _TPmap, typename _Ty, typename _Talc> LOLIX_INLINE_CALL
	archive_base<_Teh, _TPmap>&	operator << (archive_base<_Teh, _TPmap>& arc, vector<_Ty, _Talc> const& vec)
		{
		size_value sv(vec.size());
		arc << sv;
		for ( size_type i = 0; i != vec.size(); ++i )
			arc << vec[i];
		return arc;
		}

	template<typename _Teh, typename _TPmap, typename _Ty, typename _Talc> LOLIX_INLINE_CALL
	archive_base<_Teh, _TPmap>&	operator >> (archive_base<_Teh, _TPmap>& arc, vector<_Ty, _Talc>& vec)
		{
		size_value sv;
		arc >> sv;
		vec.resize((size_type)sv);
		for ( size_type i = 0; i != vec.size(); ++i )
			arc >> vec[i];
		return arc;
		}
}}
#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_VECTOR)


#if			defined(LOLIX_DEF__ARC_SUPPORT_VEC_MAP)
	#if			!defined(__LOLIX__TOY__VEC_MAP__NICK__K_IN_G__)
		#include	"./vec_map.hpp"
	#endif	//	!defined(__LOLIX__TOY__VEC_MAP__NICK__K_IN_G__)
namespace lolix{namespace toy{
	template<typename _Teh, typename _TPmap, typename _TKey, typename _TMap, typename _TLess, typename _TAlc>
	archive_base<_Teh, _TPmap>& operator << (archive_base<_Teh, _TPmap>& arc, vec_multimap<_TKey, _TMap, _TLess, _TAlc> const& m)
		{
		arc << m.size();
		for ( vec_multimap<_TKey, _TMap, _TLess, _TAlc>::const_iterator iter = m.begin(), end = m.end()
			; iter != end
				; ++iter )
			{
			arc << iter->first << iter->second;
			}
		}
	template<typename _Teh, typename _TPmap, typename _TKey, typename _TMap, typename _TLess, typename _TAlc>
	archive_base<_Teh, _TPmap>& operator >> (archive_base<_Teh, _TPmap>& arc, vec_multimap<_TKey, _TMap, _TLess, _TAlc>& m)
		{
		size_type sz;
		arc >> sz;
		m.reserver(sz);
		for ( size_type i = 0; i != sz; ++i )
			{
			_TKey k;
			_TMap m;
			arc >> k >> m;
			m.insert(k, m);
			}
		}
	template<typename _Teh, typename _TPmap, typename _TKey, typename _TMap, typename _TLess, typename _TAlc>
	archive_base<_Teh, _TPmap>& operator << (archive_base<_Teh, _TPmap>& arc, vec_map<_TKey, _TMap, _TLess, _TAlc> const& m)
		{
		arc << m.size();
		for ( vec_multimap<_TKey, _TMap, _TLess, _TAlc>::const_iterator iter = m.begin(), end = m.end()
			; iter != end
				; ++iter )
			{
			arc << iter->first << iter->second;
			}
		return arc;
		}
	template<typename _Teh, typename _TPmap, typename _TKey, typename _TMap, typename _TLess, typename _TAlc>
	archive_base<_Teh, _TPmap>& operator >> (archive_base<_Teh, _TPmap>& arc, vec_map<_TKey, _TMap, _TLess, _TAlc>& m)
		{
		size_type sz;
		arc >> sz;
		m.reserve(sz);
		for ( size_type i = 0; i != sz; ++i )
			{
			_TKey k;
			_TMap v;
			arc >> k >> v;
			m.insert(k, v);
			}
		return arc;
		}
}}
#endif	//	defined(LOLIX_DEF__ARC_SUPPORT_VEC_MAP)


//--------------------------------------------------------------------------
//==============================================================================
#endif	//	!defined(__LOLIX_TOY__ARCHIVE__SUPPORTED_UDT__NICK__K_IN_G__)
